package br.edu.ifrn.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;

import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

@Entity
public class Documento implements Serializable{
	
	@Id 
	@SequenceGenerator(name = "seq_documento", sequenceName = "seq_documento", allocationSize = 1)
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_documento")
	private Long id;
	
	@ManyToOne
	@JoinColumn(name="fk_tipoDoc")
	private TipoDocumento tipo;
	
	@ManyToOne
	@JoinColumn(name="fk_classeDoc")
	private ClasseDocumento classe;
	
	@LazyCollection(LazyCollectionOption.FALSE)
	@OneToMany(cascade={CascadeType.ALL})
	@JoinColumn(name="fk_metavalores")
	private List<Metavalor> metavalores;
	private Date dataCadastro;
	private Date dataEntrada;
	private int operadorCad;
	private int operadorAlt;
	@OneToOne(cascade = CascadeType.ALL)
	private Arquivo arquivo;  
	private boolean descartado;
	private boolean passivelDescarte;
	  
	public Documento(TipoDocumento tipo, ClasseDocumento classe,List<Metavalor> metavalores,
			Date dataCadastro, Date dataEntrada, int operadorCad,
			int operadorAlt) {
		super();
		this.tipo = tipo;
		this.classe = classe;
		this.metavalores = metavalores;
		this.dataCadastro = dataCadastro;
		this.dataEntrada = dataEntrada;
		this.operadorCad = operadorCad;
		this.operadorAlt = operadorAlt;
		this.descartado = false;
	}

	public Documento() {
		super();
		this.descartado = false;
		metavalores = new ArrayList<Metavalor>();
	}
	
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
	
	public TipoDocumento getTipo() {
		return tipo;
	}

	public void setTipo(TipoDocumento tipo) {
		this.tipo = tipo;
	}

	public ClasseDocumento getClasse() {
		return classe;
	}

	public void setClasse(ClasseDocumento classe) {
		this.classe = classe;
	}
	
	public List<Metavalor> getMetavalores() {
		return metavalores;
	}

	public void setMetavalores(List<Metavalor> metavalores) {
		this.metavalores = metavalores;
	}

	public Date getDataCadastro() {
		return dataCadastro;
	}

	public void setDataCadastro(Date dataCadastro) {
		this.dataCadastro = dataCadastro;
	}

	public Date getDataEntrada() {
		return dataEntrada;
	}

	public void setDataEntrada(Date dataEntrada) {
		this.dataEntrada = dataEntrada;
	}

	public int getOperadorCad() {
		return operadorCad;
	}

	public void setOperadorCad(int operadorCad) {
		this.operadorCad = operadorCad;
	}

	public int getOperadorAlt() {
		return operadorAlt;
	}

	public void setOperadorAlt(int operadorAlt) {
		this.operadorAlt = operadorAlt;
	}
	public boolean isPassivelDescarte(){
		Calendar dataCadastro = new GregorianCalendar();
		dataCadastro.setTime(this.getDataCadastro());
		passivelDescarte = (Calendar.getInstance().get(Calendar.YEAR)
				- dataCadastro.get(Calendar.YEAR) >= this.getClasse()
				.getTemporalidade().getPrazoGuarda() && !this.descartado);
		return passivelDescarte;
		
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Documento other = (Documento) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

	public boolean isDescartado() {
		return descartado;
	}

	public void setDescartado(boolean descartado) {
		this.descartado = descartado;
	}
	
	public String getListMetavalores(){
		String result = "";
		for(Metavalor m: metavalores) {
			result += m.getMetadado().getDescricao()+": "+ m.getValor() + "; ";
		}
		
		return result;
	}

	public Arquivo getArquivo() {
		return arquivo;
	}

	public void setArquivo(Arquivo arquivo) {
		this.arquivo = arquivo;
	}

}
